/*
 * Copyright (c) 2020 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
#include "ohos_init.h"
#include "cmsis_os2.h"
 
#include "hi_wifi_api.h"
//#include "wifi_sta.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
 
#include "lwip/sockets.h"
 
#include "MQTTPacket.h"
#include "transport.h"

#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"

int mqtt_rc = 0;
int mqtt_sock = 0;
int mqtt_len = 0;
unsigned char mqtt_buf[200];
int mqtt_buflen = sizeof(mqtt_buf);
int mqtt_req_qos = 0;
int mqtt_msgid = 1;
int toStop = 0;
MQTTString topicString = MQTTString_initializer;
int connectedflag=0;
void mqtt_exit(void){
	transport_close(mqtt_sock);
	mqtt_rc = mqtt_rc;
	printf("[MQTT] ERROR EXIT\n");
}
void mqtt_onmessage(void){
	if (MQTTPacket_read(mqtt_buf, mqtt_buflen, transport_getdata) == PUBLISH){
			unsigned char dup;
			int qos;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in;
			unsigned char* payload_in;
			int rc;
			MQTTString receivedTopic;
			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
					&payload_in, &payloadlen_in, mqtt_buf, mqtt_buflen);								// 接收数据
			printf("message arrived %.*s\n", payloadlen_in, payload_in);

            mqtt_rc = rc;
			if(strncmp("D0011", (const char *)payload_in, strlen("D0011")) == 0)
			{
				GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
			}
			if(strncmp("D0010", (const char *)payload_in, strlen("D0010")) == 0)
			{
				GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
			}
        }
}
int mqtt_subscribe(char * topic){	// MQTT订阅
	/* subscribe */
	topicString.cstring = topic;
	mqtt_len = MQTTSerialize_subscribe(mqtt_buf, mqtt_buflen, 0, mqtt_msgid, 1, &topicString, &mqtt_req_qos);	// MQTT订阅
	mqtt_rc = transport_sendPacketBuffer(mqtt_sock, mqtt_buf, mqtt_len);									// 传输发送缓冲区
	if (MQTTPacket_read(mqtt_buf, mqtt_buflen, transport_getdata) == SUBACK) 	/* wait for suback */	// 等待订阅返回
	{
		unsigned short submsgid;
		int subcount;
		int granted_qos;
 
		mqtt_rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, mqtt_buf, mqtt_buflen);
		if (granted_qos != 0){
			printf("granted qos != 0, %d\n", granted_qos);
			mqtt_exit();
			return 0;
		}
 
		return 1;
	}else{
		mqtt_exit();
		return 0;
	}
}
int mqtt_publish(char * topic,double Hum,double Temp){	// MQTT发布
	/* publish */
	topicString.cstring = topic;
	char text[10];
	char payload[50];
	//float Temp=36.5;
	unsigned char dev_id=001;
	//memset(text, 0, sizeof(text));
	strcpy(payload, "{");
	sprintf(text, "\"Temp\":%.2f,",Temp);
	strcat(payload, text);
	memset(text, 0, sizeof(text));
	sprintf(text, "\"Hum\":%.2f",Hum);
	strcat(payload, text);
	strcat(payload, "}");
	memset(text, 0, sizeof(text));
	int payloadlen = strlen(payload);
	if((mqtt_len = MQTTSerialize_publish(mqtt_buf, mqtt_buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen))<=0){
		return 1;
	}
	//if(mqtt_rc = transport_sendPacketBuffer(mqtt_sock, mqtt_buf, mqtt_len)!=mqtt_len){
	if(transport_sendPacketBuffer(mqtt_sock, mqtt_buf, mqtt_len)!=mqtt_len){
		return 2;
	}
	printf("publish success\n");
	return 0;
}
 
int mqtt_init(void){		// MQTT初始化开始连接
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	char *host = "183.230.40.39";		// 地址
	int port = 6002;					// 端口
 
	
	mqtt_sock = transport_open(host, port);
	if(mqtt_sock < 0){
		return mqtt_sock;
	}
 
	data.clientID.cstring = "deviceid";			// ClientID,设备id
	data.keepAliveInterval = 60;
	data.cleansession = 1;
	data.username.cstring = "productid";		// 用户名，产品id
	data.password.cstring = "password";	// 密码/密钥
 
	printf("[MQTT]Sending to hostname %s port %d\n", host, port);
 
	mqtt_len = MQTTSerialize_connect(mqtt_buf, mqtt_buflen, &data);		// 开始连接
	mqtt_rc = transport_sendPacketBuffer(mqtt_sock, mqtt_buf, mqtt_len);		// 发送缓冲区
 
	if (MQTTPacket_read(mqtt_buf, mqtt_buflen, transport_getdata) == CONNACK){	// 等待链接返回
		unsigned char sessionPresent, connack_rc;
 
		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, mqtt_buf, mqtt_buflen) != 1 || connack_rc != 0){
			printf("Unable to connect, return code %d\n", connack_rc);
			mqtt_exit();
			return 0;
		}
	}else{
		mqtt_exit();
		return 0;
	}
	/*GpioInit();
	IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_GPIO_DIR_OUT);*/
	connectedflag=1;
	return 1;
}
 
 
/*void mqtt_test(void){
	printf("[MQTT]Start MQTT\r\n");
    if(mqtt_init() == 1){
		printf("[MQTT]MQTT Connect\r\n");
		mqtt_subscribe("control");		//设置订阅
		while(!toStop)
		{	
			mqtt_onmessage();
			//if(mqtt_publish("TOP1")!=0){
			//	printf("publish failed");
			//}
			osDelay(100);
		}
		//mqtt_task();
	}
}*/
void mqttbeatTask(void){	// MQTT心跳包
	while(1){

	mqtt_len = MQTTSerialize_pingreq(mqtt_buf, mqtt_buflen);
	transport_sendPacketBuffer(mqtt_sock, mqtt_buf, mqtt_len);
	osDelay(100);
	if ((MQTTPacket_read(mqtt_buf, mqtt_buflen, transport_getdata) == PUBLISH)||(MQTTPacket_read(mqtt_buf, mqtt_buflen, transport_getdata) == PINGRESP)){
		printf("connected\n");
		connectedflag=1;
	}
	else{
		connectedflag=0;
		printf("failed,reconnect\n");
		if(mqtt_init()==1){
		mqtt_subscribe("control");
		}
	}
	osDelay(1000);	
	}
}
void mqttreceTask(void){	// MQTT定时接收
	while(1){
		if(connectedflag==1){
			mqtt_onmessage();
		}

		osDelay(100);
	}
}
// mqtt心跳
void mqtt_Thread(void){
    osThreadAttr_t mqttattr;
    mqttattr.name = "mqttbeatTask";
    mqttattr.attr_bits = 0U;
    mqttattr.cb_mem = NULL;
    mqttattr.cb_size = 0U;
    mqttattr.stack_mem = NULL;
    mqttattr.stack_size = 10240;
    mqttattr.priority =osPriorityNormal;
 
    if (osThreadNew((osThreadFunc_t)mqttbeatTask, NULL, &mqttattr) == NULL) {
        printf("[mqttbeat] Falied to create mqttbeatTask!\n");
    }
}
// mqtt接收
void mqttrec_Thread(void){
    osThreadAttr_t mqttrecattr;
    mqttrecattr.name = "mqttreceTask";
    mqttrecattr.attr_bits = 0U;
    mqttrecattr.cb_mem = NULL;
    mqttrecattr.cb_size = 0U;
    mqttrecattr.stack_mem = NULL;
    mqttrecattr.stack_size = 10240;
    mqttrecattr.priority =osPriorityNormal;
 
    if (osThreadNew((osThreadFunc_t)mqttreceTask, NULL, &mqttrecattr) == NULL) {
        printf("[mqttrec] Falied to create mqttreceTask!\n");
    }
}